package com.utils;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.support.test.InstrumentationRegistry;
import android.support.v4.app.ActivityCompat;
import android.text.TextUtils;
import android.util.Log;

import com.bank.Bank;
import com.entity.AuditDetectionBean;
import com.entity.BankOrder;
import com.entity.PointBean;
import com.entity.QRCodeUpLoadBean;
import com.entity.SMSCode;
import com.entity.TradeInfo;
import com.entity.User;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.show.api.util.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.utils.ChatClient.AppCode;
import static com.utils.ChatClient.AppKey;
import static com.utils.ChatClient.AppSecret;
import static com.utils.ChatClient.CODE_S;
import static com.utils.ChatClient.C_CODETOTEXTRESULT_S;
import static com.utils.ChatClient.C_CONFIRM_TRADE_S;
import static com.utils.ChatClient.C_IMAGETOTEXTRESULT_S;
import static com.utils.ChatClient.C_PAUSE_S;
import static com.utils.ChatClient.C_RESUME_S;
import static com.utils.ChatClient.C_SEND_QRCODE_STATUS_S;
import static com.utils.ChatClient.C_SEND_SMS_CODE_S;
import static com.utils.ChatClient.C_SaveDepositFlowResult_S;
import static com.utils.ChatClient.C_VERIFICATIONCODERESULT_S;
import static com.utils.ChatClient.ConfirmOrder;
import static com.utils.ChatClient.DmtAppid;
import static com.utils.ChatClient.DmtSoftkey;
import static com.utils.ChatClient.DmtUsername;
import static com.utils.ChatClient.DmtUserpwd;
import static com.utils.ChatClient.JhAppKey;
import static com.utils.ChatClient.M_SENDERROR_P;
import static com.utils.ChatClient.M_SEND_BANK_INFO_P;
import static com.utils.ChatClient.PAUSE;
import static com.utils.ChatClient.PERMISSIONS_STORAGE;
import static com.utils.ChatClient.P_AUDIT_DETECTION_S;
import static com.utils.ChatClient.P_SEND_BANK_LOGIN_INFO_M;
import static com.utils.ChatClient.P_SEND_TRADE_M;
import static com.utils.ChatClient.REQUEST_EXTERNAL_STORAGE;
import static com.utils.ChatClient.YyAppid;
import static com.utils.ChatClient.YySecret;
import static com.utils.ChatClient.bankInfo;
import static com.utils.ChatClient.detection;
import static com.utils.ChatClient.hashMap;
import static com.utils.ChatClient.list;
import static com.utils.ChatClient.pointBeansList;
import static com.utils.ChatClient.qRCodeUpLoadBean;
import static com.utils.ChatClient.smsCode;
import static com.utils.ChatClient.tradeInfo;
import static com.utils.ChatClient.userInfo;
import static com.utils.ChatClient.vrifyCodeText;
import static com.utils.ClientListener.verifyStoragePermissions;
import static java.lang.Thread.sleep;


public class ChatClient {
    public static final int REQUEST_EXTERNAL_STORAGE = 1;
    public static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE};
    public static long begintime = System.currentTimeMillis();//开始时间
    public static int overtime = 60 * 3 * 1000;//运行时间
    public static int overtimeLogin = 60 * 2 * 1000;//运行时间
    public static int overtimewait = 30 * 1000;//运行时间
    public static int overtime_1 = 1000;//运行时间
    public static int overtime_2 = 2 * 1000;//运行时间
    public static int overtime_3 = 3 * 1000;//运行时间
    public static int overtime_4 = 4 * 1000;//运行时间
    public static int overtime_5 = 5 * 1000;//运行时间
    public static int overtime_6 = 6 * 1000;//运行时间
    public static int overtime_8 = 8 * 1000;//运行时间
    public static int overtime_10 = 10 * 1000;//运行时间
    public static int overtime_12 = 12 * 1000;
    public static int overtime_15 = 15 * 1000;//运行时间
    public static int overtime_18 = 15 * 1000;//运行时间;
    public static int overtime_20 = 20 * 1000;//运行时间
    public static int overtime_25 = 25 * 1000;//运行时间
    public static int overtime_30 = 30 * 1000;//运行时间
    public static int overtime_40 = 40 * 1000;//运行时间
    public static int overtime_45 = 45 * 1000;//运行时间;
    public static int overtime_60 = 60 * 1000;//运行时间
    public static int overtime_70 = 70 * 1000;//运行时间
    public static int overtime_80 = 80 * 1000;//运行时间
    public static int overtime_90 = 90 * 1000;//运行时间
    public static int overtime_120 = 120 * 1000;//运行时间
    public static int overtime_180 = 180 * 1000;//运行时间

    public static int verifyCount = 0;

    public static String bankNameError = "银行名错误";
    public static String errorStr = "银行转账请求超时";
    public static String error = "银行转账脚本出错";
    public static String layoutLoadError = "界面加载出错";
    public static String loginError = "银行登录脚本超时";
    public static String keyIdentificationErr = "键盘识别超时";

    //客户端请求
    //客户端连接，心跳
    public static String HEARTBEAT = "heartbeat";
    // 回应客户端连接，PC向手机发送银行信息
    public static String M_SEND_BANK_INFO_P = "M_sendBankInfo_P";
    // 手机向PC请求银行登录信息，获取账号信息
    public static String M_GET_BANK_LOGIN_INFO_P = "M_getBankLoginInfo_P";
    //手机向PC发送登录结果
    public static String M_SEND_LOGIN_RESULT_P = "M_sendLoginResult_P";
    //手机返回T端转账结果
    public static String M_SEND_TRADE_RESULT_P = "M_sendTradeResult_P";
    // 手机向PC发送错误结果
    public static String M_SENDERROR_P = "M_sendError_P";
    // 手机收到错误格式Json
    public static String M_SENDERRORJSON_P = "M_sendErrorJson_P";
    // 手机订单查询请求
    public static String P_CONFIRMTRADE_M = "P_confirmTrade_M";
    // 手机订单查询返回
    public static String M_CONFIRMTRADERESULT_P = "M_confirmTradeResult_P";
    // 转账逻辑结束，等待手机订单执行反馈
    public static String M_TRANSFERFINISH_P = "M_TransferFinish_P";
    //客户端连接掉线
    public static String S_DROPPED_M = "M_dropped_P";
    // 向T端发送请求按压U盾
    public static String W_PRESSU_C = "W_pressU_C";
    // T端回应
    //PC返回登录信息
    public static String P_SEND_BANK_LOGIN_INFO_M = "P_sendBankLoginInfo_M";
    //T端下发订单
    public static String P_SEND_TRADE_M = "P_sendTrade_M";
    //订单请求
    public static String M_RUNNING_P = "M_running_P";
    // 上报剩余金额
    public static String C_UPDATEBALANCE_W = "C_updateBalance_W";
    // C端向S发送待确认订单
    public static String C_CONFIRM_TRADE_S = "C_confirmTrade_S";
    // 脚本向T端发送查账待确认订单结果
    public static String S_CONFIRM_TRADE_RESULT_C = "S_confirmTradeResult_C";

    // 脚本向控制端 请求增加工作时间
    public static String S_ADDWORKTIME_C = "S_addWorkTime_C";
    // 脚本向控制端 请求人工识别验证码
    public static String S_VERIFICATIONCODE_C = "S_verificationCode_C";
    // 控制端向脚本 发送识别验证码结果
    public static String C_VERIFICATIONCODERESULT_S = "C_verificationCodeResult_S";
    // 控制端向脚本 发送识别验证码结果
    public static String S_NOTIFICATION_C = "S_notification_C";
    //获取到图文识别结果
    public static String C_IMAGETOTEXTRESULT_S = "C_imageToTextResult_S";
    //脚本向控制端 请求图文识别
    public static String S_IMAGETOTEXT_C = "S_imageToText_C";
    //在无SIM卡情况下请求短信验证码
    public static String S_GET_SMS_CODE_C = "S_getSMSCode_C";
    //在模拟器情况下短信验证码返回
    public static String C_SEND_SMS_CODE_S = "C_sendSMSCode_S";
    //控制端向脚本 请求暂停操作
    public static String C_PAUSE_S = "C_pause_S";
    //控制端向脚本 请求恢复操作
    public static String C_RESUME_S = "C_resume_S";
    //脚本向控制端 发送已暂停操作
    public static String S_PAUSED_C = "S_paused_C";
    //云闪付订单上报返回
    public static String C_SaveDepositFlowResult_S = "C_SaveDepositFlow_Result_S";
    //新图片识别协议（用于建行）
    public static final String S_CODETOTEXT_C = "S_CodeToText_C";
    //新图片识别协议T端返回协议
    public static final String C_CODETOTEXTRESULT_S = "C_CodeToTextResult_S";
    //手机查询转账信息上报
    public static String M_SENDTRADEINFO_P = "M_sendTradeInfo_P";
    //请求图片二维码上传
    public static String J_SEND_QRCODE_BASE64_S = "J_sendQRCodeBase64_S";
    //图片二维码上传返回储存结果
    public static String C_SEND_QRCODE_STATUS_S = "C_sendQRCodeStatus_S";
    // 云闪付订单列表检测
    public static String P_AUDIT_DETECTION_S = "P_auditDetection_S";

    private static Socket server;
    static Thread thread;
    public static LinkedHashMap<String, BankOrder> hashMap = new LinkedHashMap<String, BankOrder>();
    //	public static HashMap<String, BankOrder> hashMap = new HashMap<String, BankOrder>();
    public static List<BankOrder> list = new ArrayList<BankOrder>();//转账订单对象
    public static List<PointBean> pointBeansList = new ArrayList<PointBean>();
    public static SMSCode smsCode = null;
    public static QRCodeUpLoadBean qRCodeUpLoadBean = null;
    public static boolean ConfirmOrder = false;//true:查账，false：转账
    //    public static boolean ConfirmOrder = true;//true:查账，false：转账
    public static User user;
    public static String userInfo = "";
    public static String AppKey = "";
    public static String AppSecret = "";
    public static String AppCode = "";
    public static String YyAppid = "";//易源
    public static String YySecret = "";//易源
    public static String JhAppKey = "";//聚合验证码KEY  
    public static String bankInfo = "";//接收银行信息
    public static String vrifyCodeText = "";


    public static String UsbPayEncode = "";//农行U盾型号

    public static String DmtAppid = "";//打码
    public static String DmtSoftkey = "";//打码
    public static String DmtUsername = "";//打码
    public static String DmtUserpwd = "";//打码
    public static TradeInfo tradeInfo;//云闪付上传订单信息

    public static boolean RUNING = true;//true进入转账、false返回
    public static Context context = InstrumentationRegistry.getTargetContext();
    public static String CCBMethodName = LogToFile.getMethodName();//log所在方法
    public static String CODE_S = "";//验证码
    public static int CODE_TIMER = 0;//验证码识别请求次数
    public static boolean PAUSE = true;//请求暂停：false：暂停、true：继续执行
    public final static AuditDetectionBean detection = new AuditDetectionBean();


    public static void start() {
        verifyStoragePermissions(context);
        Constants.PROT = getBankPort();//获取终端号
        LogToFile.d("=========port=========", "port：" + Constants.PROT);
        try {
            String phoneIp = getPhoneIp();
            LogToFile.d("JUnit", "连接服务，请稍后..." + phoneIp + ":" + Constants.PROT);
            server = new Socket(phoneIp, Constants.PROT);
            // 创ngxin 一个客户端接收消息进程
            new ClientListener(server).start();
            startThreadSocket(server);
        } catch (UnknownHostException e) {
            LogToFile.d("JUnit", "服务器地址不正确！----" + e.toString());
        } catch (IOException e) {
            LogToFile.d("JUnit", "与服务器连接失败！----" + e.toString());
        } catch (Exception e) {
            LogToFile.d("Junit", "与服务器" + server + ":" + Constants.PROT + "连接失败，异常信息：" + e.toString());
        }
    }

    /**
     * 获取银行名称
     *
     * @return
     */
    public static String getBankName() {
        //读取
        Map<String, String> info = FileHelper.getSavedBankInfo("yzfbank.txt");
        return info.get("bankname");
    }

    /**
     * 获取设备端口
     *
     * @return
     */
    public static int getBankPort() {
        //读取
        Map<String, String> info = FileHelper.getSavedBankInfo("yzfbank.txt");
        return Integer.parseInt(info.get("bankprot"));
    }

    public static void startThreadSocket(final Socket socket) {
        try {
            if (!socket.getKeepAlive())
                socket.setKeepAlive(true);// true，若长时间没有连接则断开
            if (!socket.getOOBInline())
                socket.setOOBInline(true);// true,允许发送紧急数据，不做处理
            final String socketContent = "<YZF>{'header':'" + HEARTBEAT + "'}</YZF>";
            thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            while (true) {
                                Thread.sleep(2 * 10000);// 20s发送一次心跳
                                OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");
                                PrintWriter pw = new PrintWriter(out, true);
                                LogToFile.d("JUnit", "心跳：" + socketContent);
                                pw.println(socketContent);
                                out.flush();
                                pw.flush();
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
            thread.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送消息写入流中，通过Socket传输
     *
     * @param str
     */
    public static void msg(String str) {
        try {
            LogToFile.d("JUnit", "回复PC端：" + str);
            OutputStreamWriter out = new OutputStreamWriter(server.getOutputStream(), "UTF-8");
            PrintWriter pw = new PrintWriter(out, true);
            pw.println(str);
            out.flush();
            pw.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取元素超时出现错误
     *
     * @param method
     */
    public static void timer(String method, String errorStr) {
        //String imgName = ImageView.getScreenshot(getBankName());
        String imgName = "";
        if (list.size() > 0) {
            msg("<YZF>{'header':'" + ChatClient.M_SENDERROR_P + "','devices':'" + getSerialNumber() + "','order':'" + list.get
                    (0).getOrder() + "','info':'" + errorStr + "','code':'" + method + "','imgName':'" + imgName + "'}</YZF>");
        } else {
            msg("<YZF>{'header':'" + ChatClient.M_SENDERROR_P + "','devices':'" + getSerialNumber() + "','info':'" + errorStr +
                    "','code':'" + method + "','imgName':'" + imgName + "'}</YZF>");
        }
        setDevicesLog(errorStr);
        LogToFile.d("JUnit方法", method);
        LogToFile.d("JUnit原因", errorStr);
    }

    public static boolean getState(String args1, String args2) {
        Log.d("====args1-====", "=====args1========" + args1 + "=====args2========" + args2);
        if (!args1.equals("") && !args2.equals("")) {
            String[] res = args2.split("发送");
            String sumMoney = res[1];
            sumMoney = sumMoney.replaceAll("为", "");
            System.out.println(sumMoney);
            if (args1.contains(sumMoney)) {
                System.out.println("包含");
                return true;
            } else {
                System.out.println("不包含");
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * 获取验证码
     *
     * @return
     */
    public static String getCodeS() {
        msg("<YZF>{'header':'" + ChatClient.S_VERIFICATIONCODE_C + "','codeImage':''}</YZF>");
        try {
            sleep(1000);
            while (true) {
                System.out.print("");
                if (!"".equals(CODE_S)) {
                    break;
                }
            }
            LogToFile.d("JUnit", "C端返回验证码：" + CODE_S);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return CODE_S;
    }

    /**
     * 获取验证码
     *
     * @param bankName
     * @return
     */
    public static String getCodeS(String bankName) {
        vrifyCodeText = "";
        msg("<YZF>{'header':'" + ChatClient.S_CODETOTEXT_C + "','bankName':'" + bankName + "'}</YZF>");
        try {
            sleep(1000);
            ChatClient.begintime = System.currentTimeMillis();
            while (true) {
                long nowTime = System.currentTimeMillis();
                sleep(1000);
                if (ChatClient.begintime - nowTime > 60 * 1000) {
                    ChatClient.timer(bankName, "获取图形验证码超时");
                    return "";
                }
                if (!TextUtils.isEmpty(vrifyCodeText)) {
                    break;
                }
            }
            LogToFile.d("JUnit", "C端返回验证码：" + vrifyCodeText);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return vrifyCodeText;
    }

    /**
     * 申请增加时间
     *
     * @param time
     */
    public static void addWorkTime(int time) {
        msg("<YZF>{'header':'" + ChatClient.S_ADDWORKTIME_C + "','time':" + time + "}</YZF>");
        LogToFile.d("JUnit", "增加时间：" + time);
    }

    /**
     * 在无卡操作时点击获取短信验证码
     */
    public static SMSCode requestSMSCode(String userName, String bankId) {
        smsCode = null;
        try {
            ChatClient.begintime = System.currentTimeMillis();
            while (true) {
                long nowtime = System.currentTimeMillis();
                if ((nowtime - ChatClient.begintime) > ChatClient.overtime_30) {
                    LogToFile.d("JUnit", "T端短信请求超时");
                    break;
                }
                LogToFile.d("JUnit", "请求—————" + userName.substring(userName.length() - 4, userName.length()) + "短信验证码");
                msg("<YZF>{'header':'" + ChatClient.S_GET_SMS_CODE_C + "','username':'" + userName + "','bankId':'" + bankId + "'}</YZF>");
                sleep(ChatClient.overtime_5);
                if (smsCode != null && !StringUtils.isEmpty(smsCode.getSmscode())) {
                    LogToFile.d("JUnit", "T端返回验证码：" + smsCode.getSmscode());
                    break;
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return smsCode;
    }


    /**
     * 请求订单
     */
    public static void request() {
        msg("<YZF>{'header':'" + ChatClient.M_RUNNING_P + "'}</YZF>");
        LogToFile.d("JUnit", "运行中.....");
    }


    /**
     * 等待订单时，暂停脚本
     */
    public static void S_paused_C() {
        msg("<YZF>{'header':'" + ChatClient.S_PAUSED_C + "'}</YZF>");
        LogToFile.d("JUnit", "暂停成功");
    }

    /**
     * 剩余金额
     */
    public static void C_updateBalance_W(Double balance) {
        msg("<YZF>{'header':'" + ChatClient.C_UPDATEBALANCE_W + "','balance':" + balance + "}</YZF>");
        LogToFile.d("JUnit", "剩余金额" + balance);
    }

    /**
     * 剩余金额
     */
    public static void C_updateBalance_W(String balance) {
        msg("<YZF>{'header':'" + ChatClient.C_UPDATEBALANCE_W + "','balance':" + balance + "}</YZF>");
        LogToFile.d("JUnit", "剩余金额" + balance);
    }

    /**
     * 上传查询到的转账账单
     */
    public static void M_sendTradeInfo_P(String json) {
        String mag = "<YZF>{'header':'" + ChatClient.M_SENDTRADEINFO_P + "'," + json + "}</YZF>";
        msg(mag);
        LogToFile.d("JUnit", "上传查寻账单" + mag);
    }

    public static void uploadQRCodeBase64(String QRCodeImagePath) {
        String machineId = "";
        if (!TextUtils.isEmpty(bankInfo)) {
            String[] infos = bankInfo.split(" ");
            machineId = infos[1];
        }
        msg("<YZF>{'header':'" + ChatClient.J_SEND_QRCODE_BASE64_S + "','prot':'" + machineId + "'," +
                "'image':'" + QRCodeImagePath + "'}</YZF>");
        LogToFile.d("JUnit", "上传QRCodeBase64");
    }

    public static String replaceBlank(String str) {
        String dest = "";
        if (str != null) {
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }


    /**
     * app登录成功
     */
    public static void loginS() {
        msg("<YZF>{'header':'" + ChatClient.M_SEND_LOGIN_RESULT_P + "','devices':'" + getSerialNumber() + "'," +
                "'balance':'--'}</YZF>");
        LogToFile.d("JUnit", "登录成功：" + "<YZF>{'header':'" + ChatClient.M_SEND_LOGIN_RESULT_P + "','devices':'" +
                getSerialNumber() + "','balance':'--'}</YZF>");
        LogToFile.d("====登录成功====", "===登录成功====");
    }

    /**
     * U盾请求
     * times:点击次数
     */
    public static void pressu(String times) {
        count++;
        msg("<YZF>{'header':'" + ChatClient.W_PRESSU_C + "','times':'" + times + "','count':'" + count + "'}</YZF>");
        LogToFile.d("JUnit", "请求点击U盾，点击次数：" + times);
        LogToFile.d("====请求点击U盾====", "===请求点击U盾====");
    }

    /**
     * 上报查账结果
     */
    public static void reportAuditOrder(String state, Bank bank) {
        String message = "";
        switch (state) {
            case "0":
                message = "交易成功";
                break;
            case "1":
                message = "交易待处理...";
                break;
            case "4":
                message = "未查到条目";
                break;
            case "6":
                message = "查账列表无账单数据";
                break;
        }
        String mobileD = "'devices':'" + getSerialNumber() + "','prot':'" + Constants.PROT + "','phoneModel':'" + bank.BANK_NAME + "','info':'" +
                message + "'";
        String json = "'order':'" + list.get(0).getOrder() + "','balance':'" + bank.sumMoney + "','state':" + state + ",'type':" + list.get(0)
                .getType();
        ChatClient.msg("<YZF>{'header':'" + ChatClient.S_CONFIRM_TRADE_RESULT_C + "'," + json + "," + mobileD + "}</YZF>");
        //删除处理过的订单
        mapDelete(list.get(0).getOrder());
        getmap();
    }

    /**
     * 上报转账结果
     */
    public static void reportTransferOrder(String bankName, String message, String sumMoney, int state) {
        String mobileD = "'devices':'" + getSerialNumber() + "','prot':'" + Constants.PROT + "','phoneModel':'" + bankName + "','info':'" + message
                + "'";
        String json = "'order':'" + list.get(0).getOrder() + "','balance':'" + sumMoney + "','state':" + state + ",'type':" + list.get(0).getType();
        ChatClient.msg("<YZF>{'header':'" + ChatClient.M_SEND_TRADE_RESULT_P + "'," + json + "," + mobileD + "}</YZF>");
        //删除处理过的订单
        mapDelete(list.get(0).getOrder());
        getmap();
    }

    public static int count = 0;

    /**
     * 获取手机ip地址
     *
     * @return
     */
    public static String getPhoneIp() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                        return inetAddress.getHostAddress().toString();
                    }
                }
            }
        } catch (Exception e) {
        }
        return "";
    }

    // 删除订单
    public static void mapDelete(String key) {
        Iterator<Map.Entry<String, BankOrder>> it = hashMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, BankOrder> entry = it.next();
            String key1 = entry.getKey();
            if (key.equals(key1)) {
                LogToFile.d("---删除订单---", key + "---删除订单---" + entry.getValue().getBankName());
                //                System.out.printf("delete key:%s value:%s\r\n", key, entry.getValue().getBankName());
                it.remove();
            }
        }
    }

    // 完整遍历Map
    public static void getmap() {
        list.clear();
        Iterator it = hashMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, BankOrder> entry = (Map.Entry) it.next();
            list.add(entry.getValue());
        }
    }


    /**
     * 判定存在订单
     */
    public static boolean existOrder() {
        boolean isOrder = false;
        if (list.size() > 0) {
            isOrder = true;
        }
        return isOrder;
    }

    /**
     * 等待订单
     *
     * @return true为有订单，false为没有订单
     */
    public static boolean waitExistOrder(int sleepTime) {
        int requestTime = sleepTime / 2000;
        for (int i = 0; i <= sleepTime / 1000; i++) {
            if (existOrder()) {
                LogToFile.d("---等待订单---", "有订单");
                return true;
            } else {
                try {
                    sleep(ChatClient.overtime_1);
                } catch (InterruptedException e) {
                    LogToFile.d("---等待订单---", "---等待订单错误：" + e.getMessage());
                }
                if (i % requestTime == 0) {
                    request();
                }
            }
        }
        return false;
    }

    //获取手机序列号
    public static String getSerialNumber() {
        String devices = android.os.Build.SERIAL;
        return devices;
    }

    /**
     * 获取当前本地apk的版本
     *
     * @param mContext
     * @return
     */
    public static String getVersionCode(Context mContext) {
        String versionCode = "0.0.0";
        try {
            //获取软件版本号，对应AndroidManifest.xml下android:versionCode
            versionCode = mContext.getPackageManager().
                    getPackageInfo(mContext.getPackageName(), 0).versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return versionCode;
    }

    /**
     * 删除处理中订单,如登录时无订单则不处理
     *
     * @param Exception
     */
    public static void setDevicesLog(String Exception) {
        if (list.size() > 0) {
            //删除处理过的订单
            mapDelete(list.get(0).getOrder());
            getmap();
            LogToFile.d("---捕获异常，删除订单---", "---捕获异常，删除订单---" + Exception);
        }
        String devicesLog = "设备号=" + getSerialNumber() + "&银行=" + getBankName() + "&版本号=" + getVersionCode(context);
        LogToFile.d("JUnit", "异常设备对应银行：" + devicesLog + "\n" + Exception);
    }
}


class ClientListener extends Thread {
    private Socket server;
    private String useType;

    public ClientListener(Socket server) {
        this.server = server;
    }

    @Override
    public void run() {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(server.getInputStream(), "UTF-8"));
            String message = null;
            while ((message = br.readLine()) != null && message.length() > 0) {
                String str = message.trim();
                if (!StringUtils.isEmpty(str) && str.contains("<YZF>") && str.contains("</YZF>")) {
                    String strFormsocket = str.replace("<YZF>", "").replace("</YZF>", "");
                    strFormsocket = strFormsocket.trim();
                    if (!"".equals(strFormsocket) && isGoodJson(strFormsocket)) {
                        setObj(strFormsocket);
                    } else {
                        LogToFile.d("JUnit", "数据格式不是json");
                    }
                } else {
                    LogToFile.d("JUnit", "收到非法数据");
                }
            }
        } catch (IOException e) {
            LogToFile.d("JUnit", server.getInetAddress().getHostName() + "接收消息失败");
            System.exit(-1);
        }
    }

    //数据归类
    public void setObj(String json) {
        LogToFile.w("JUnit", "手机接收到T端消息:" + json);
        JsonParser parser = new JsonParser();
        JsonObject object = (JsonObject) parser.parse(json);
        try {
            if (M_SEND_BANK_INFO_P.equals(object.get("header").getAsString())) {
                String devices = object.get("devices").getAsString();
                String port = object.get("prot").getAsString();
                String phoneModel = object.get("phoneModel").getAsString();
                if (TextUtils.isEmpty(devices)) {
                    bankInfo = "devices" + " " + port + " " + phoneModel;
                } else if (TextUtils.isEmpty(port)) {
                    bankInfo = devices + " port" + " " + phoneModel;
                } else if (TextUtils.isEmpty(phoneModel)) {
                    bankInfo = devices + " " + port + " " + " phoneModel";
                } else {
                    bankInfo = devices + " " + port + " " + phoneModel;
                }
                LogToFile.d("chatClient", "bankInfo ==== " + bankInfo);
            }
        } catch (Exception e) {
            bankInfo = "";
        }

        if (C_CODETOTEXTRESULT_S.equals(object.get("header").getAsString())) {
            LogToFile.d("JUnit", "接收到T端验证码识别结果");
            String codeStr = object.get("code").getAsString();
            if (TextUtils.isEmpty(codeStr)) {
                LogToFile.d("JUnit", "未接收到验证码");
                vrifyCodeText = "###";
            } else {
                vrifyCodeText = codeStr;
            }
        }

        if (C_SaveDepositFlowResult_S.equals(object.get("header").getAsString())) {
            LogToFile.d("JUnit", "上传订单返回值解析开始");
            tradeInfo = new TradeInfo();
            try {
                tradeInfo.setBalance(object.get("balance").getAsString());
                tradeInfo.setMachineId(object.get("machineId").getAsString());
                tradeInfo.setMoney(object.get("money").getAsString());
                tradeInfo.setNumbered(object.get("numbered").getAsString());
                tradeInfo.setPayer(object.get("payer").getAsString());
                tradeInfo.setPayerBank(object.get("payerBank").getAsString());
                tradeInfo.setPayerCard(object.get("payerCard").getAsString());
                tradeInfo.setTradingTime(object.get("tradingTime").getAsString());
                tradeInfo.setCode(object.get("code").getAsString());
                tradeInfo.setStatus(object.get("status").getAsString());
                tradeInfo.setMessage(object.get("message").getAsString());
                tradeInfo.setMark(object.get("mark").getAsString());
            } catch (Exception e) {
                LogToFile.d("JUnit", "上传订单返回值解析失败 object = " + object + " Exception = " + e.getMessage());
                setError(e.getMessage());
            }

            LogToFile.d("JUnit", "上传订单返回值解析完成 tradeInfo : " + tradeInfo.toString());
        }

        if (P_SEND_BANK_LOGIN_INFO_M.equals(object.get("header").getAsString())) {
            if (!"".equals(object.get("userName").getAsString()) && !"".equals(object.get("pwd").getAsString()) && !"".equals
                    (object.get("bankpwd").getAsString())) {
                userInfo = object.get("userName").getAsString() + " " + object.get("pwd").getAsString() + " " + object.get
                        ("bankpwd").getAsString() + " " + object.get("usbPayPwd").getAsString() + " " + object.get("UseType").getAsString() + " " +
                        object.get("bankId").getAsString()+" "+object.get("userName").getAsString();
                useType = object.get("UseType").getAsString();
                //阿里云第三方
                AppKey = object.get("AppKey").getAsString();
                AppSecret = object.get("AppSecret").getAsString();
                AppCode = object.get("AppCode").getAsString();
                //易源
                YyAppid = object.get("YyAppid").getAsString();
                YySecret = object.get("YySecret").getAsString();
                //聚合
                JhAppKey = object.get("JhAppKey").getAsString();
                //农行U盾型号
                //UsbPayEncode = object.get("UsbPayEncode").getAsString();
                //DmtAppid = "105083";
                //DmtSoftkey = "O2V5nlUq2Ycp+9KqFcHmCB9S59o2+a2b";
                //DmtUsername = "yazheng";
                //DmtUserpwd = "yazheng123";
                //打码兔
                DmtAppid = object.get("DmtAppid").getAsString();
                DmtSoftkey = object.get("DmtSoftkey").getAsString();
                DmtUsername = object.get("DmtUsername").getAsString();
                DmtUserpwd = object.get("DmtUserpwd").getAsString();

            } else {
                String meg = "用户名和密码不为空！";
                setError(meg);
            }
        } else if (P_SEND_TRADE_M.equals(object.get("header").getAsString()) || C_CONFIRM_TRADE_S.equals(object.get("header").getAsString())) {//处理PC端返回的数据赋值BankOrder对象
            if (useType.equals("0") || object.get("devices").getAsString().equals(ChatClient.getSerialNumber())) {
                //if (true) {
                if (P_SEND_TRADE_M.equals(object.get("header").getAsString())) {
                    ConfirmOrder = false;
                } else if (C_CONFIRM_TRADE_S.equals(object.get("header").getAsString())) {
                    ConfirmOrder = true;
                }
                LogToFile.d("JUnit", "ConfirmOrder：true时查账，false为转账：===" + ConfirmOrder);
                LogToFile.d("JUnit", "手机接收到订单信息：===" + object);
                BankOrder order = new BankOrder();
                //设备号
                String devices = object.get("devices").toString();
                //转账类型
                String type = object.get("type").toString();
                //订单号
                String order1 = object.get("order").toString();
                //收款人
                String userName = object.get("userName").toString();
                //收款银行
                String bankName = object.get("bankName").toString();
                //收款人卡号
                String bankNo = object.get("bankNo").toString();
                //转账金额
                String money = object.get("money").toString();
                //开户行
                try {
                    String bankAdr = object.get("openingBank").toString();
                    LogToFile.d("====订单中的开户行==", "订单中的开户行地址===:" + bankAdr);
                } catch (Exception e) {
                    e.printStackTrace();
                    LogToFile.d("----T端返回没有开户行字段-----", "-------T端返回没有开户行字段------");
                }

                if (!"null".equals(devices) && !"null".equals(type) && !"null".equals(order1) && !"null".equals(userName) &&
                        !"null".equals(bankName) && !"null".equals(bankNo) && !"null".equals(money)) {
                    if ("".equals(object.get("devices").getAsString())) {
                        String meg = "订单错误,设备号不为空";
                        setError(meg);
                        return;
                    }
                    if ("".equals(object.get("order").getAsString())) {
                        String meg = "订单错误,订单号不为空";
                        setError(meg);
                        return;
                    }
                    if ("".equals(object.get("userName").getAsString())) {
                        String meg = "订单错误,收款人姓名不为空";
                        setError(meg);
                        return;
                    }
                    if ("".equals(object.get("bankName").getAsString())) {
                        String meg = "订单错误,收款银行名称不为空";
                        setError(meg);
                        return;
                    }
                    if ("".equals(object.get("bankNo").getAsString())) {
                        String meg = "订单错误,收款银行卡号不为空";
                        setError(meg);
                        return;
                    }
                    if ("".equals(object.get("money").getAsString())) {
                        String meg = "订单错误,转账金额不为空";
                        setError(meg);
                        return;
                    }
                    order.setDevices(object.get("devices").getAsString().replaceAll(" ", ""));
                    order.setType(object.get("type").getAsString());
                    order.setOrder(object.get("order").getAsString());
                    order.setUserName(object.get("userName").getAsString().replaceAll(" ", ""));
                    order.setBankName(object.get("bankName").getAsString().replaceAll(" ", ""));
                    order.setBankNo(object.get("bankNo").getAsString().replaceAll(" ", ""));
                    order.setMoney(object.get("money").getAsString().replaceAll(" ", ""));
                    try {
                        order.setBankAdr(object.get("openingBank").getAsString().replaceAll(" ", ""));
                    } catch (Exception e) {
                        e.printStackTrace();
                        LogToFile.d("----T端返回没有开户行字段-----", "-------T端返回没有开户行字段，解析错误------");
                    }

                    hashMap.put(object.get("order").getAsString().replaceAll(" ", ""), order);
                    list.add(order);
                } else {
                    String meg = "订单错误,订单中不应该出现null";
                    setError(meg);
                }
            } else {
                String meg = "订单错误,银行和设备不匹配！";
                LogToFile.d("设备devices号：", object.get("devices").getAsString() + "=========" + ChatClient.getSerialNumber());
                setError(meg);
            }
        } else if (C_VERIFICATIONCODERESULT_S.equals(object.get("header").getAsString())) {//识别验证码结果
            CODE_S = object.get("code").getAsString();
            LogToFile.d("====识别验证码CODE_S==", "识别验证码CODE_S===:" + CODE_S);
        } else if (C_IMAGETOTEXTRESULT_S.equals(object.get("header").getAsString())) {//识别U盾键盘结果
            //KEYBOARD = object.get("text").getAsString();
            PointBean pointBean;
            String charPointsStr = object.get("charPoints").getAsString();
            JsonParser parser2 = new JsonParser();
            JsonArray array = (JsonArray) parser2.parse(charPointsStr);
            if (pointBeansList != null && pointBeansList.size() > 0) {
                pointBeansList.clear();
            }
            for (int i = 0; i < array.size(); i++) {
                pointBean = new PointBean();
                JsonObject ob = array.get(i).getAsJsonObject();
                if (ob != null) {
                    pointBean.setCharStr(ob.get("Char").getAsString());
                    pointBean.setX(ob.get("X").getAsInt());
                    pointBean.setY(ob.get("Y").getAsInt());
                    pointBeansList.add(pointBean);
                }
            }
            LogToFile.d("KEYBOARD", "pointBeansList==" + pointBeansList.size());
        } else if (C_PAUSE_S.equals(object.get("header").getAsString())) {
            LogToFile.d("JUnit", "请求暂停操作");
            PAUSE = false;
        } else if (C_RESUME_S.equals(object.get("header").getAsString())) {
            LogToFile.d("JUnit", "请求恢复操作");
            PAUSE = true;
        } else if (M_SENDERROR_P.equals(object.get("header").getAsString())) {
            //            System.exit(-1);
            LogToFile.d("JUnit", "重新请求Socket链接");
            ChatClient.start();
        } else if (C_SEND_SMS_CODE_S.equals(object.get("header").getAsString())) {
            smsCode = new SMSCode();
            smsCode.setSmscode(object.get("smscode").getAsString());
            smsCode.setTelephone(object.get("telephone").getAsString());
        } else if (C_SEND_QRCODE_STATUS_S.equals(object.get("header").getAsString())) {
            qRCodeUpLoadBean = new QRCodeUpLoadBean();
            qRCodeUpLoadBean.setMachineId(object.get("machineId").getAsString());
            qRCodeUpLoadBean.setSaveTime(object.get("saveTime").getAsString());
            qRCodeUpLoadBean.setState(object.get("state").getAsString());
            LogToFile.d("JUnit", "收到二维码更新状态返回：" + qRCodeUpLoadBean.toString());
        } else if (P_AUDIT_DETECTION_S.equals(object.get("header").getAsString())) {
            String machineId = object.get("machineId").getAsString();
            if (machineId.equals(bankInfo.split(" ")[1])) {
                String date = object.get("date").getAsString();
                String isDetection = object.get("isDetection").getAsString();
                detection.setMachineId(machineId);
                detection.setDate(date);
                detection.setIsDetection(isDetection);
                if (isDetection.equals("0")) {
                    LogToFile.d("JUnit", "本终端云闪付查询开启");
                } else if (isDetection.equals("1")) {
                    LogToFile.d("JUnit", "本终端云闪付查询关闭");
                }
            }
        }
    }

    /**
     * 订单错误,字段不应该出现NULL
     */
    public void setError(String str) {
        String message = "<YZF>{'header':'" + ChatClient.M_SENDERRORJSON_P + "','info':'" + str + "'}</YZF>";
        LogToFile.d("JUnit", "错误信息回复：" + message);
        ChatClient.msg(message);
    }

    /**
     * 检测字符串是否为json串
     *
     * @param json
     * @return
     */
    public static boolean isGoodJson(String json) {
        try {
            new JsonParser().parse(json);
            return true;
        } catch (JsonParseException e) {
            LogToFile.d("JUnit", "json错误：" + json);
            return false;
        }
    }

    public static void verifyStoragePermissions(Context context) {
        int permission = ActivityCompat.checkSelfPermission(context,
                Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (permission != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions((Activity) context, PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE);
        }
    }

}
